package com.darkness.rpc.framework.consumer;

import com.darkness.rpc.framework.common.Invocation;
import com.darkness.rpc.framework.protocol.RequestHandler;
import com.darkness.rpc.registercenter.Register;
import com.darkness.rpc.registercenter.common.RegisteredServiceInfo;
import org.apache.dubbo.common.extension.ExtensionLoader;
import java.lang.reflect.Proxy;

/**
 * @author darkness
 * @time 2022/3/7 12:48
 * @description
 */
public class RpcConsumer<T> {

    private String group;

    private Class<T> itfClass;

    private String version;

    private RequestHandler handler;

    public RpcConsumer(String group, Class<T> itfClass, String version, String protocol) {
        this.group = group;
        this.itfClass = itfClass;
        this.version = version;
        this.handler = ExtensionLoader.getExtensionLoader(RequestHandler.class).getExtension(protocol);
    }

    @SuppressWarnings("unchecked")
    public T getConsumer(String registry) {
        return (T) Proxy.newProxyInstance(RpcConsumer.class.getClassLoader(), new Class[]{itfClass}, (proxy, method, args) -> {
            Class<?>[] parameterTypes = method.getParameterTypes();
            Class<?> returnType = method.getReturnType();
            Invocation invocation = new Invocation();
            invocation.setInterfaceName(itfClass.getName());
            invocation.setGroup(group);
            invocation.setArgs(args);
            invocation.setMethodName(method.getName());
            invocation.setVersion(version);
            invocation.setParamTypes(parameterTypes);
            Register register = ExtensionLoader.getExtensionLoader(Register.class).getExtension(registry);
            RegisteredServiceInfo service = register.getService(group, version, itfClass.getName());
            return handler.handleRequest(service.getHostName(), service.getPort(), invocation, returnType);
        });
    }

}
